class UploadPlug {
    divEle: HTMLElement | null = null
    type: Array<string> = []
    size: number = Infinity
    callback: Function = () => { }
    isCompress: boolean = false
    compressQuality: number = 0.92
    constructor() {
        this.divEle = document.getElementById('uploadDivId') || document.createElement('div');
        const flag = this.divEle.hasAttribute('id')
        if (!flag) {
            this.divEle.setAttribute('id', 'uploadDivId')
        }
        document.body.appendChild(this.divEle)
    }
    // 处理文件
    handleFile(files: any) {
        const _this = this;
        const callback = this.callback;
        const successList: any = [];
        const failList: any = [];
        for (let i = 0; i < files.length; i++) {
            const item = files[i];
            const { flag, ...restParams } = this.checkFile(item);
            if (!flag) {
                failList.push(restParams);
                continue;
            }
            const isImage = item.type.indexOf('image') !== -1;
            let res = new Promise((resolve, reject) => {
                let reader = new FileReader();
                reader.readAsDataURL(item);
                reader.onload = function () {
                    let base64Url = reader.result;
                    const fileName = item.name;
                    if (_this.isCompress && isImage) {
                        const target: Promise<File> = _this.compressImage(base64Url, fileName);
                        target.then((res: any) => {
                            resolve(res);
                        }).catch((err: any) => {
                            reject(err);
                        })
                    } else {
                        item.base64Url = base64Url;
                        item.fileType = fileName.substring(fileName.lastIndexOf('.') + 1); // 提取后缀名
                        resolve(item);
                    }
                }
            })
            successList.push(res);
        }
        Promise.all(successList)
            .then(data => {
                callback({ successList: data, failList })
            }).catch(err => {
                console.log(err, 'err');
            })
    }
    // 校验文件类型和大小
    checkFile(file: any,) {
        const type = this.type
        const size = this.size
        const { name, size: newSize } = file;
        const fileType: string = name.substring(name.lastIndexOf('.') + 1).toLowerCase();
        const fileSize = Number((newSize / 1024).toFixed(1)) // kb;
        const typeFlag = type.length > 0 && !type.includes(fileType);
        const sizeFlag = size && fileSize > size;
        if (typeFlag && sizeFlag) {
            return {
                flag: false,
                fileType,
                fileSize: fileSize + 'kb',
                reason: '文件类型、大小不符合要求',
                file
            }
        };
        if (typeFlag) {
            return {
                flag: false,
                fileType,
                reason: '文件类型不符合要求',
                file
            }
        };
        if (sizeFlag) {
            return {
                flag: false,
                fileSize: fileSize + 'kb',
                reason: '文件大小不符合要求',
                file
            }
        }
        return {
            flag: true,
        }
    }
    // 压缩图片
    compressImage(file: any, fileName: string) {
        const _this = this;
        const quality = this.compressQuality
        const img = new Image();
        return new Promise<File>((resolve, reject) => {
            img.src = file;
            img.onload = function () {
                const canvas = document.createElement('canvas');
                const ctx: any = canvas.getContext('2d');
                const originWidth = img.width;
                const originHeight = img.height;
                canvas.width = originWidth;
                canvas.height = originHeight;
                ctx.drawImage(img, 0, 0, originWidth, originHeight);
                const dataUrl = canvas.toDataURL('image/jpeg', quality);
                const newFile: any = _this.dataURLtoFile(dataUrl, fileName);
                newFile.base64Url = dataUrl;
                newFile.fileType = fileName.substring(fileName.lastIndexOf('.') + 1)
                resolve(newFile);
            }
        })
    }
    // base64转file
    dataURLtoFile(dataUrl: any, filename: any) {
        const arr = dataUrl.split(',');
        const mime = arr[0].match(/:(.*?);/)[1];
        const bstr = atob(arr[1]);
        let n = bstr.length;
        const u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new File([u8arr], filename, { type: mime });
    }
    // 本地/拍照上传
    async localUpload({
        type = [],
        size = Infinity, // 校验文件大小
        isCompress = false, // 是否压缩图片
        compressQuality = 0.92, // 压缩质量
        callback = () => { },
        accepts,
        multiple = true,
        camera = false,
    }: any) {
        this.type = type;
        this.size = size;
        this.isCompress = isCompress;
        this.compressQuality = compressQuality;
        this.callback = callback;
        (this.divEle as HTMLElement).innerHTML = '';
        const _this = this;
        // const isIE = /msie|trident/.test(navigator.userAgent.toLowerCase());
        const isIE = "ActiveXObject" in window;
        if (isIE) {
            (window as any).inputChange = function (event: any) {
                let files = event.target.files
                _this.handleFile(files)
            }
            let inputEle = `<input id="inputEleId" type="file" onchange="(function(event){inputChange(event)})(event)" style="display:none;"/>`;
            (this.divEle as HTMLElement).innerHTML = inputEle;
            (document.getElementById('inputEleId') as HTMLElement).click();
        } else {
            let inputEle = document.createElement('input');
            inputEle.setAttribute('type', 'file');
            if (multiple) {
                inputEle.setAttribute('multiple', 'multiple');
            }
            if (accepts) {
                inputEle.setAttribute('accept', accepts);
            }
            if (camera) {
                inputEle.setAttribute('capture', 'camera');
            }
            let id = new Date().getTime();
            inputEle.setAttribute('id', id.toString());
            inputEle.style.display = 'none';
            (this.divEle as HTMLElement).appendChild(inputEle);
            inputEle.click();
            inputEle.onchange = function (event: any) {
                let files = event.target.files || inputEle.files || (document.getElementById(id.toString()) as any).files;
                _this.handleFile(files);
            }
        }
    }

}
export default UploadPlug




